
#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>
#include <QGraphicsProxyWidget>
#include <QGraphicsSceneMouseEvent>

#include <QApplication>
#include <QEvent>
#include <QPoint>
#include <QKeyEvent>
#include <QRect>
#include <QDesktopWidget>
#include <QPainter>

#include "clippinglabel.h"
#include "WPData.h"
#include "wpcommentgraphicslist.h"
#include "wpcommentgraphicslistitem.h"
#include "WPNetworkEngine.h"
#include "MDragWidget.h"
#include "themedatastorage.h"
#include "busyindicator.h"
#include "wpcommongeometry.h"
#include "utils.h"

#include "HtmlPainter.h"

//WPCommentGraphicsListItem::StandardGeometry WPCommentGraphicsListItem::iStandardGeometry;

WPCommentGraphicsListItem::WPCommentGraphicsListItem(const WPComment aComment, bool aShowFullComment, BusyIndicator& aBusyIndicator, ThemeData& aThemeData)
	: WPGraphicsListItem(aBusyIndicator, aThemeData)
    , iComment(aComment)
    , iShowFullComment(aShowFullComment)
    , iExpansionHasEffect(true)
{
    
    iDate = aComment->GetShortLocalTimeString(); 
    
    iTitle = new HtmlPainter(HtmlPainter::Info, iThemeData);
    iText = new HtmlPainter(HtmlPainter::Content, iThemeData);
    Update(iComment);
}

WPCommentGraphicsListItem::~WPCommentGraphicsListItem()
{
    delete iTitle;
	delete iText;
}

void WPCommentGraphicsListItem::SetAvatarImage(const QPixmap &aPixmap)
{
    if (!aPixmap.isNull())
        iPixmap = aPixmap;
}

WPComment WPCommentGraphicsListItem::GetComment() const
{
    return iComment;
}

void WPCommentGraphicsListItem::Update(WPComment aComment)
{
    // XXX: no-op?
    iComment = aComment;
    
    iTitle->setContent(tr("to %1").arg(iComment->iPostTitle));
    iText->setContent(Utils::toDisplayHtml(iComment->iContent));
    
    SetTitleFormatting();
}

bool WPCommentGraphicsListItem::operator<(WPCommentGraphicsListItem const & other)
{
    return iComment->GetLocalTime() < other.iComment->GetLocalTime();
}

void WPCommentGraphicsListItem::ChangeViewMode()
{
    prepareGeometryChange();
    iShowFullComment = !iShowFullComment;
    SetViewMode(iShowFullComment);
}

void WPCommentGraphicsListItem::paintContent(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
{
    StandardGeometry & geometry = iShowFullComment ? iExpandedGeometry : iStandardGeometry;
    
    // Common part
    if (!iPixmap.isNull())
    {
        // TODO default avatar from themestorage?
        painter->drawPixmap(geometry.iPixmap.topLeft(), iPixmap);
    }
    
    painter->setPen(Qt::black);
    painter->setFont(*iThemeData.iListInfoFont);
    
    QFontMetrics fm(painter->font());
    QRect const & authorRect(geometry.iAuthor); 
    painter->drawText(authorRect, fm.elidedText(iComment->iAuthor, Qt::ElideRight, authorRect.width()));
    painter->drawText(geometry.iDate, Qt::TextDontClip, iDate);
    
    iTitle->paint(painter, geometry.iTitle);
    iText->paint(painter, geometry.iComment);
    
    painter->setFont(*iThemeData.iListInfoFont);
    if(iComment->iAuthorUrl.length())
    {
        painter->drawText(geometry.iEmail, iComment->iAuthorEmail, QTextOption(Qt::AlignRight));
        painter->drawText(geometry.iWebsite, iComment->iAuthorUrl, QTextOption(Qt::AlignRight));
    }
    else
    {
        painter->drawText(geometry.iWebsite, iComment->iAuthorEmail, QTextOption(Qt::AlignRight));
    }
}

bool WPCommentGraphicsListItem::IsBusy()
{
    return iComment->IsBusy();
}

bool WPCommentGraphicsListItem::HasError()
{
    return iComment->iError;
}

void WPCommentGraphicsListItem::handleGeomeryChange()
{
    SetViewMode(iShowFullComment);
    iExpansionHasEffect = (iExpandedGeometry.height() > iStandardGeometry.height());
}

void WPCommentGraphicsListItem::SetViewMode(bool aShowFullComment)
{
    if (aShowFullComment)
    {   
        iStandardGeometry.update(*this);
        iExpandedGeometry.update(*this);
        setMinimumHeight(iExpandedGeometry.height());
    }
    else
    {
        iExpandedGeometry.update(*this);
        iStandardGeometry.update(*this);
        setMinimumHeight(iStandardGeometry.height());
    }
}

void WPCommentGraphicsListItem::SetTitleFormatting()
{
    HtmlPainter::FormatRangeList titleFormatting;
    QTextLayout::FormatRange italicRange;    
    
    QString const & title = iTitle->ConvertToDisplayForm(iComment->iPostTitle);
    italicRange.start = iTitle->getContent().indexOf(title);
    italicRange.length = title.length();
    
    italicRange.format.setFont(iTitle->getFont());
    italicRange.format.setFontItalic(true);
    
    titleFormatting.append(italicRange);
    iTitle->SetFormatting(titleFormatting);
}

WPCommentGraphicsListItem::StandardGeometry::StandardGeometry()
  : iHeight(0)
    { }

void WPCommentGraphicsListItem::StandardGeometry::update(WPCommentGraphicsListItem & parent)
    {
    if(iInitSize == parent.size()) { return; }
    
    int gravatarSize = WPDataGravatars::Size();
    int padding = parent.iThemeData.iListItemInternalPadding;
    int hMargin = parent.iThemeData.iListItemContentHMargin;
    int vMargin = parent.iThemeData.iListItemContentVMargin;
    
    // Font metrics
    QFontMetrics infoFm(*parent.iThemeData.iListInfoFont);
    
    // Layout rects
    iPixmap.setRect(hMargin, vMargin, gravatarSize, gravatarSize);
    iAuthor.setRect(hMargin, iPixmap.bottom() + padding, gravatarSize, infoFm.height());
    iDate.setRect(hMargin, iAuthor.bottom(), gravatarSize, infoFm.height());
    
    int remainingWidth = parent.size().width() - iPixmap.right() - (padding + hMargin);
    int col2x = iPixmap.right() + 2 * padding;

    // resize HTML text rects
    iTitle.setX(col2x);
    iTitle.setY(hMargin);
    iTitle.setSize(parent.iTitle->setOneLineMode(remainingWidth));

    iComment.setX(col2x);
    iComment.setY(iTitle.bottom() + padding);
    iComment.setSize(parent.iText->setLimitedMode(remainingWidth, 2));  // XXX: two lines

    int emailTop = std::max(iAuthor.top(), iComment.bottom() + padding);
    iEmail.setRect(col2x, emailTop, remainingWidth, infoFm.height());
    iWebsite.setRect(col2x, iEmail.bottom(), remainingWidth, infoFm.height());
    
    updateHeight(parent.iThemeData);
    iInitSize = parent.size();
    }

void WPCommentGraphicsListItem::StandardGeometry::updateHeight(ThemeData const & theme)
    {
    iHeight = std::max(iDate.bottom(), iWebsite.bottom()) +
              theme.iListItemContentVMargin;
    }

void WPCommentGraphicsListItem::ExpandedGeometry::update(WPCommentGraphicsListItem & parent)
    {
    if(iInitSize == parent.size()) { return; }
    
    StandardGeometry::update(parent);
    
    int padding = parent.iThemeData.iListItemInternalPadding;
    
    iTitle.setSize(parent.iTitle->setUnlimitedMode(iTitle.width()));
    
    iComment.setSize(parent.iText->setUnlimitedMode(iComment.width()));
    iComment.setY(iTitle.bottom() + padding);
    
    int emailTop = std::max(iAuthor.top(), iComment.bottom() + padding);
    iEmail.moveTop(emailTop);
    iWebsite.moveTop(iEmail.bottom());
    
    updateHeight(parent.iThemeData);
    iInitSize = parent.size();
    }

